<script setup lang="ts">
  import { useFindTemplateById } from '@/views/order/custom/hooks/useTemplateList'
  import { computed, ref, watch } from 'vue'
  import { ComponentListItem, ComponentType, DataConnectTable } from '../../hooks/types'
  import CustomInput from '@/views/order/custom/form/component-list/CustomInput.vue'
  import CustomTextarea from '@/views/order/custom/form/component-list/CustomTextarea.vue'
  import CustomRadio from '@/views/order/custom/form/component-list/CustomRadio.vue'
  import CustomCheckbox from '@/views/order/custom/form/component-list/CustomCheckbox.vue'
  import CustomSingleSelect from '@/views/order/custom/form/component-list/CustomSingleSelect.vue'
  import CustomMultipleSelect from '@/views/order/custom/form/component-list/CustomMultipleSelect.vue'
  import CustomDateTime from '@/views/order/custom/form/component-list/CustomDateTime.vue'
  import CustomFileUpload from '@/views/order/custom/form/component-list/CustomFileUpload.vue'
  import CustomAddress from '@/views/order/custom/form/component-list/CustomAddress.vue'
  import CustomDataConnect from '@/views/order/custom/form/component-list/custom-data-connect/Index.vue'
  import CustomChildForm from '@/views/order/custom/form/component-list/CustomChildForm.vue'
  import CustomDivider from '@/views/order/custom/form/component-list/CustomDivider.vue'
  import {
    useFindOrderById,
    useOrderDel,
    useOrderUpdate,
    useOrderEnd,
  } from '@/views/order/custom/hooks/useOrder'
  import { ElMessageBox, FormInstance } from 'element-plus'
  import moment from 'moment'
  import _ from 'lodash'
  import { useRouter } from 'vue-router'

  defineOptions({
    name: 'OrderCustomDataDetailModal',
  })

  const { template, findLoading, findTemplate } = useFindTemplateById()
  const { order, findOrderLoading, findOrder } = useFindOrderById()
  const { delLoading, del } = useOrderDel()
  const { orderForm, updateLoading, update } = useOrderUpdate()
  const { endLoading, end } = useOrderEnd()

  const props = defineProps({
    templateId: {
      type: String,
      required: true,
    },
    orderId: {
      type: String,
      required: true,
    },
  })

  const emits = defineEmits<{
    (e: 'update'): void
  }>()

  const visible = defineModel('visible', { type: Boolean, default: false })
  const componentWidthList = computed(() => {
    const widthMap: Record<ComponentListItem['width'], string> = {
      1: '100%',
      '1/2': '50%',
      '1/3': '33.33%',
      '1/4': '25%',
    }

    return template.value.componentList.map((component) => widthMap[component.width])
  })
  const activeTab = ref<'flow' | 'comment'>('flow')
  const unDisabledComponentIds = computed(() => {
    if (!isCurrentNodeStart.value) {
      return []
    }

    const node = order.value.flow.nodes.find((item) => item.id === order.value.currentNodeId)
    if (node) {
      return node.fieldPermissions.filter((item) => item.edit).map((item) => item.fieldId)
    }
    return []
  })
  const isCurrentNodeStart = ref(false)
  const rules = computed(() => {
    return template.value.componentList.map((item) => {
      if (
        item.required &&
        !item.beControlVisible &&
        !unDisabledComponentIds.value.includes(item.id)
      ) {
        if (item.type === 'address') {
          return [
            {
              validator: (rule, value, callback) => {
                if (!value.province || !value.city || !value.area || !value.address) {
                  callback(new Error(`${item.label}不能为空`))
                } else {
                  callback()
                }
              },
              trigger: ['change', 'blur'],
            },
          ]
        }

        if (item.type === 'child-form') {
          return [
            {
              validator: (rule, value, callback) => {
                value = value.filter((data) => {
                  let isAllFieldFixed = true
                  for (const key in data) {
                    if (!data[key].isFixed) {
                      isAllFieldFixed = false
                    }
                  }
                  return !isAllFieldFixed
                })
                if (value && value.length <= 0) {
                  callback(new Error(`${item.label}不能为空`))
                  return
                }
                callback()
              },
              trigger: ['change', 'blur'],
            },
          ]
        }

        if (item.type === 'data-connect') {
          return [
            {
              validator: (rule, value, callback) => {
                const componentId = rule.field.split('.')[0]
                if (!orderForm.value.form[componentId].dataConnectVal) {
                  callback(new Error(`${item.label}不能为空`))
                  return
                }
                callback()
              },
              trigger: ['change', 'blur'],
            },
          ]
        }

        return [{ required: true, message: `${item.label}不能为空`, trigger: ['change', 'blur'] }]
      }

      return []
    })
  })
  const eventHandle = {
    customDataConnectChange: (component: ComponentListItem, selectData: DataConnectTable) => {
      component.dataConnectConfig.fillRules.forEach((item) => {
        const data = selectData[0]
        if (data && orderForm.value.form[item.toFieldId] && item.fillMode === 2) {
          orderForm.value.form[component.id].dataConnectVal = data.id

          const fillComponent = template.value.componentList.find(
            (component) => component.id === item.toFieldId,
          )
          if (fillComponent && !fillComponent.beControlVisible) {
            orderForm.value.form[item.toFieldId].inputVal = data[item.fromField]
          }
        }
      })
    },
    customSingleSelectChange: (component: ComponentListItem, value: string) => {
      component.singleSelectConfig.beControlVisibleRules.forEach((rule) => {
        const componentIndex = template.value.componentList.findIndex(
          (item) => item.id === rule.componentId,
        )
        if (componentIndex === -1) {
          return
        }
        if (rule.optionValue === value) {
          template.value.componentList[componentIndex].beControlVisible = false
        } else {
          template.value.componentList[componentIndex].beControlVisible = true
        }
      })
    },
  }
  const formInstance = ref<FormInstance | null>(null)
  const eventStartTime = ref(0)
  const currentNode = computed(() => {
    return orderForm.value.flow.nodes.find((item) => item.id === orderForm.value.currentNodeId)
  })
  const router = useRouter()

  const onDelClick = () => {
    ElMessageBox({
      title: '提示',
      message: '确定要删除该数据吗？',
      showCancelButton: true,
      type: 'warning',
      autofocus: false,
      async beforeClose(action, instance, done) {
        if (action === 'confirm') {
          del(props.orderId)
          emits('update')
          visible.value = false
        }
        done()
      },
    })
  }

  const findNodeById = (nodeId: string) => {
    const node = order.value.flow.nodes.find((item) => item.id === nodeId)
    if (node) {
      return {
        name: node.name,
        isStart: node.isStart,
        isEnd: node.isEnd,
      }
    }
    return {
      name: '',
      isStart: false,
      isEnd: false,
    }
  }

  const getFormItemProp = (componentItem: ComponentListItem) => {
    const formItemPropMap: Record<ComponentType, Array<string>> = {
      input: [componentItem.id, 'inputVal'],
      textarea: [componentItem.id, 'textareaVal'],
      radio: [componentItem.id, 'radioVal'],
      checkbox: [componentItem.id, 'checkboxVal'],
      'single-select': [componentItem.id, 'singleSelectVal'],
      'multiple-select': [componentItem.id, 'multipleSelectVal'],
      'date-time': [componentItem.id, 'datetimeVal'],
      'file-upload': [componentItem.id, 'fileUploadVal'],
      address: [componentItem.id, 'addressVal'],
      'data-connect': [componentItem.id, 'dataConnectVal'],
      'child-form': [componentItem.id, 'childFormVal'],
      divider: [],
    }

    return formItemPropMap[componentItem.type]
  }

  const onCurrentFlowClick = () => {
    isCurrentNodeStart.value = true
    eventStartTime.value = new Date().getTime()
  }

  const onCancelClick = () => {
    isCurrentNodeStart.value = false
    orderForm.value.form = _.cloneDeep(order.value.form)
  }

  const hideDrawer = () => {
    visible.value = false
    orderForm.value.form = {}
    isCurrentNodeStart.value = false
  }

  const onSaveClick = async () => {
    if (!formInstance.value) {
      return
    }

    try {
      await formInstance.value.validate()
      update(eventStartTime.value || new Date().getTime())
      hideDrawer()
      emits('update')
    } catch (error) {
      // error
    }
  }

  const init = async () => {
    await findTemplate(props.templateId)
    await findOrder(props.orderId)
    orderForm.value = _.cloneDeep(order.value)
  }

  const onFlowEnd = async () => {
    await end(props.orderId)
    hideDrawer()
    emits('update')
  }

  const onCopyOrderClick = () => {
    hideDrawer()
    navigator.clipboard.writeText(props.orderId)
    router.push({ path: `/order/custom/initiate/process/${props.templateId}` })
  }

  watch(visible, async (value) => {
    if (value) {
      init()
    }
  })
</script>

<template>
  <h-drawer
    v-model="visible"
    :width="1080"
    unit="px"
    :loading="findLoading || findOrderLoading || delLoading || updateLoading || endLoading"
    @close="hideDrawer"
  >
    <div class="detail-container">
      <div class="form-container">
        <div class="header">
          <template v-if="!isCurrentNodeStart">
            <h-plain-button type="error" @click="onDelClick">删除</h-plain-button>
            <h-plain-button v-if="currentNode && !currentNode.isEnd" type="error" @click="onFlowEnd"
              >结束流程</h-plain-button
            >
            <h-plain-button @click="onCopyOrderClick">复制工单</h-plain-button>
          </template>
          <template v-else>
            <h-button type="primary" @click="onSaveClick">保存</h-button>
            <h-button @click="onCancelClick">取消</h-button>
          </template>
        </div>
        <div class="form">
          <el-form
            ref="formInstance"
            label-position="top"
            class="component-list"
            inline-message
            :model="orderForm.form"
          >
            <template
              v-for="(component, componentIndex) in template.componentList"
              :key="componentIndex"
            >
              <el-form-item
                v-if="!component.beControlVisible"
                :style="{
                  width: component.type === 'divider' ? '100%' : componentWidthList[componentIndex],
                }"
                :label="component.label"
                class="component-item"
                :rules="rules[componentIndex]"
                :prop="getFormItemProp(component)"
              >
                <custom-divider
                  v-if="component.type === 'divider'"
                  :divider-color="component.dividerConfig.dividerColor"
                  :desc="component.dividerConfig.desc"
                  :style="component.dividerConfig.style"
                  :title="component.dividerConfig.title"
                  :title-color="component.dividerConfig.titleColor"
                  disabled
                />
                <custom-input
                  v-if="component.type === 'input' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].inputVal"
                  :amount-max="component.inputConfig.amountMax"
                  :maxlength="component.inputConfig.maxLength"
                  :mode="component.inputConfig.mode"
                  :number-max="component.inputConfig.numberMax"
                  :placeholder="component.inputConfig.placeholder"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-textarea
                  v-if="component.type === 'textarea' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].textareaVal"
                  :placeholder="component.textareaConfig.placeholder"
                  :maxlength="component.textareaConfig.maxLength"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-radio
                  v-if="component.type === 'radio' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].radioVal"
                  :options="component.radioConfig.options"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-checkbox
                  v-if="component.type === 'checkbox' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].checkboxVal"
                  :options="component.checkboxConfig.options"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-single-select
                  v-if="component.type === 'single-select' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].singleSelectVal"
                  :placeholder="component.singleSelectConfig.placeholder"
                  :options="component.singleSelectConfig.options"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                  @change="(val: string) => eventHandle.customSingleSelectChange(component, val)"
                />
                <custom-multiple-select
                  v-if="component.type === 'multiple-select' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].multipleSelectVal"
                  :placeholder="component.multipleSelectConfig.placeholder"
                  :options="component.multipleSelectConfig.options"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-date-time
                  v-if="component.type === 'date-time' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].datetimeVal"
                  :placeholder="component.dateTimeConfig.placeholder"
                  :datetime-type="component.dateTimeConfig.dateTimeType"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-file-upload
                  v-if="component.type === 'file-upload' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].fileUploadVal"
                  :num="component.fileUploadConfig.num"
                  :size="component.fileUploadConfig.size"
                  :upload-type="component.fileUploadConfig.type"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-address
                  v-if="component.type === 'address' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].addressVal"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
                <custom-data-connect
                  v-if="component.type === 'data-connect' && orderForm.form[component.id]"
                  :data-type="component.dataConnectConfig.type"
                  :field-list="component.dataConnectConfig.fieldList"
                  :select-mode="2"
                  :field-show-list-after-select="component.dataConnectConfig.showFormFieldList"
                  :selected-row-ids="[orderForm.form[component.id].dataConnectVal]"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                  @change="(list: DataConnectTable) => eventHandle.customDataConnectChange(component, list)"
                />
                <custom-child-form
                  v-if="component.type === 'child-form' && orderForm.form[component.id]"
                  v-model="orderForm.form[component.id].childFormVal"
                  :field-list="component.childFormConfig"
                  :disabled="!unDisabledComponentIds.includes(component.id)"
                />
              </el-form-item>
            </template>
          </el-form>
        </div>
      </div>
      <div class="process-container">
        <!-- <div class="header">
          <div
            :class="{ tab: true, 'active-tab': activeTab === 'flow' }"
            @click="activeTab = 'flow'"
            >流程动态</div
          >
          <div
            :class="{ tab: true, 'active-tab': activeTab === 'comment' }"
            @click="activeTab = 'comment'"
            >评论</div
          >
        </div> -->
        <div v-if="activeTab === 'flow'" class="process-list">
          <div v-if="!findNodeById(order.currentNodeId).isEnd" class="flow current">
            <div class="flow-title">{{ findNodeById(order.currentNodeId).name }}</div>
            <div class="flow-content">
              <div class="flow-author">负责人：张三</div>
              <div class="flow-content-divider"></div>
              <div class="flow-operate" @click="onCurrentFlowClick">前往处理</div>
            </div>
          </div>
          <div v-for="(flow, flowIndex) in order.flowHistory" :key="flowIndex" class="flow history">
            <div class="flow-title">{{ findNodeById(flow.nodeId).name }}</div>
            <div class="flow-content">
              <div class="flow-author">处理人：张三</div>
              <div class="flow-content-divider"></div>
              <div class="flow-start-tiem"
                >开始处理：{{ moment(flow.startTime).format('YYYY-MM-DD hh:MM:ss') }}</div
              >
              <div class="flow-duration"
                >处理耗时：{{ flow.duration ? flow.duration / 1000 : 0 }}秒</div
              >
            </div>
          </div>
        </div>
      </div>
    </div>
  </h-drawer>
</template>

<style scoped lang="scss">
  .detail-container {
    display: flex;
    height: 100%;

    .form-container {
      flex: 1;
      width: 0;
      height: 100%;
      box-sizing: border-box;
      border: 1px solid #ebecee;
      border-right: none;
      display: flex;
      flex-direction: column;

      .header {
        border-bottom: 1px solid #ebecee;
        padding: 12px;
        display: flex;
        column-gap: 8px;
      }

      .form {
        padding: 6px;
        flex: 1;
        height: 0;
        overflow-y: auto;
      }

      .component-list {
        display: flex;
        flex-wrap: wrap;
        height: fit-content;

        .component-item {
          box-sizing: border-box;
          padding: 6px;

          :deep(.el-form-item__label) {
            margin: 0;
            font-weight: bold;
            color: #000;
            font-size: 14px !important;
            padding: 5px 0;
          }

          :deep(.el-form-item__content) {
            display: flex;
            flex-direction: column;
            align-items: flex-start;

            .el-form-item__error {
              margin: 0;
            }
          }
        }
      }
    }

    .process-container {
      width: 300px;
      height: auto;
      background-color: #f5f6f8;
      border: 1px solid #ebecee;
      display: flex;
      flex-direction: column;

      .header {
        display: flex;
        height: 40px;

        .tab {
          display: flex;
          align-items: center;
          padding: 0 8px;
          cursor: pointer;
          box-sizing: border-box;
        }

        .active-tab {
          position: relative;
          color: #007cff;

          &::before {
            content: '';
            position: absolute;
            left: 8px;
            right: 8px;
            height: 2px;
            background-color: #007cff;
            bottom: 0;
          }
        }
      }

      .process-list {
        flex: 1;
        width: 100%;
        height: 0;
        padding: 12px;
        box-sizing: border-box;
        overflow-y: scroll;

        .flow {
          margin-bottom: 24px;

          .flow-title {
            color: #141e31;
            font-weight: bold;
            height: 24px;
            line-height: 24px;
            margin-bottom: 8px;
          }

          .flow-content {
            width: 100%;
            background-color: #fff;
            padding: 12px;
            box-sizing: border-box;
            border-radius: 6px;

            .flow-author {
              height: 20px;
            }

            .flow-content-divider {
              border: solid #ebecee;
              border-width: 1px 0 0;
              margin: 8px 0;
              width: 100%;
            }

            .flow-start-tiem {
              color: #838892;
            }

            .flow-duration {
              color: #838892;
              margin-top: 4px;
            }

            .flow-operate {
              color: #007cff;
              text-align: center;
              cursor: pointer;
            }
          }
        }
      }
    }
  }
</style>
